package org.chen.shiro;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.chen.model.domain.Menu;
import org.chen.model.domain.Role;
import org.chen.model.domain.Users;
import org.chen.model.service.MenuService;
import org.chen.model.service.RoleService;
import org.chen.model.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Author: 陈亮
 * @Date: 2019/3/24 14:29
 */
@Slf4j
@Component
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UsersService usersService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private MenuService menuService;

    @Override
    public String getName() {
        return "ShiroRealm";
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("----shiro开始授权操作----");
        Object principal = principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (principal instanceof Users) {
            Users users = (Users) principal;
            if (users != null) {
                queryRoleAndPermissionByAccountId(info, users);
            }
        }
        log.info("roles: {}", info.getRoles());
        log.info("permissions: {}", info.getStringPermissions());
        return info;
    }

    /***
     * 通过用户编号获取该用户的角色、权限集合
     * @param info
     * @param users
     */
    private void queryRoleAndPermissionByAccountId(SimpleAuthorizationInfo info, Users users) {
        List<Role> roleList = roleService.findRoleByAccountId(users.getId());
        if (CollectionUtils.isNotEmpty(roleList)) {
            for (Role r : roleList) {
                info.addRole(r.getEname());
                List<Menu> menuList = menuService.findByRoleId(r.getId());
                if (CollectionUtils.isNotEmpty(menuList)) {
                    for (Menu m : menuList) {
                        info.addStringPermission(m.getPermission());
                    }
                }
            }
        }
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String account = usernamePasswordToken.getUsername();
        String password = new String(usernamePasswordToken.getPassword());
        Users user = usersService.findByAccount(account);
        if (user != null) {
            if (user.getDelFlag().equals("0")) {
                log.info("账号被禁用:{}", user.getAccount());
                return null;
            }
            Users loginUser = usersService.findByAccountAndPassword(account, password);
            if (loginUser == null) {
                log.info("密码错误:{}", user.getAccount());
                return null;
            }
            log.info("认证成功:{}", user.getAccount());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), getName());
            return info;
        }
        log.info("账号不存在");
        return null;
    }

}
